package com.linhui.rpc.server;

import com.linhui.rpc.model.RpcRequest;
import com.linhui.rpc.model.RpcResponse;
import com.linhui.rpc.registry.LocalRegistry;
import com.linhui.rpc.serializer.Serializer;
import com.linhui.rpc.serializer.imp.JDKSerializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;


import javax.lang.model.element.VariableElement;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author: 临晖
 * @since: 2024-05-10
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {



    private Serializer serializer = new JDKSerializer();



    @Override
    public void handle(HttpServerRequest httpServerRequest) {
        final Serializer serializer = new JDKSerializer();
        //打印日志
        System.out.println("Received request: " + httpServerRequest.method() + "  " + httpServerRequest.uri());

        //处理请求
        httpServerRequest.bodyHandler(body -> {
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            //构建响应对象
            RpcResponse rpcResponse = new RpcResponse();
            //反序列化 - 获取请求参数
            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            if (rpcRequest == null) {
                rpcResponse.setMessage("请求参数为空");

                return;
            }

            //通过全类名获取类对象
            try {
                //通过中本地注册获取对应类对象啊
                Class<?> cla = LocalRegistry.get(rpcRequest.getServiceName());

                if (cla == null) {
                    //todo 降级处理
                    rpcResponse.setMessage("没有对应服务");
                    doResponse(httpServerRequest, rpcResponse, serializer);
                    return;
                }

                Method method = cla.getDeclaredMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                if (method == null) {
                    //todo 降级处理
                    rpcResponse.setMessage("没有对应服务");
                    doResponse(httpServerRequest, rpcResponse, serializer);
                    return;
                }
                //调用
                Object res = method.invoke(cla.newInstance(), rpcRequest.getArgs());
                //封装返回结果
                rpcResponse.setData(res);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setException(e);
                rpcResponse.setMessage(e.getMessage());
            }


            //响应
            doResponse(httpServerRequest, rpcResponse, serializer);

        });
    }


    /**
     *
     * 响应
     *
     * @param httpServerRequest
     * @param rpcResponse
     * @param serializer
     */
    void doResponse(HttpServerRequest httpServerRequest, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse response = httpServerRequest.response().
                putHeader("content-type", "application/json");

        try {
            byte[] bytes = serializer.serialize(rpcResponse);
            response.end(Buffer.buffer(bytes));
        } catch (IOException e) {
            e.printStackTrace();
            response.end(Buffer.buffer());
        }
    }
}
